/*
 * @Author: laladuduqq 2807523947@qq.com
 * @Date: 2025-08-04 17:25:01
 * @LastEditors: laladuduqq 2807523947@qq.com
 * @LastEditTime: 2025-09-06 08:48:50
 * @FilePath: /threadx_learn/tools/ulog/ulog_port.c
 * @Description: 
 */
#include "ulog_port.h"
#include "bsp_uart.h"
#include "compoent_config.h"
#include "dwt.h"
#include "tx_api.h"
#include "ulog.h"
#include <stdio.h>
#include "shell.h"


#if !SHELL_ENABLE
// 声明UART设备指针
static UART_Device* log_uart = NULL;
#endif
// 声明互斥锁，用于保护日志输出
static TX_MUTEX log_mutex;

// ANSI颜色代码定义
#define COLOR_RESET     "\033[0m"
#define COLOR_RED       "\033[31m"
#define COLOR_GREEN     "\033[32m"
#define COLOR_YELLOW    "\033[33m"
#define COLOR_BLUE      "\033[34m"
#define COLOR_MAGENTA   "\033[35m"
#define COLOR_CYAN      "\033[36m"
#define COLOR_WHITE     "\033[37m"

// 根据日志级别获取颜色
static const char* get_color_by_level(ulog_level_t level) {
    switch (level) {
        case ULOG_CRITICAL_LEVEL:
        case ULOG_ERROR_LEVEL:
            return COLOR_RED;
        case ULOG_WARNING_LEVEL:
            return COLOR_YELLOW;
        case ULOG_INFO_LEVEL:
            return COLOR_GREEN;
        case ULOG_DEBUG_LEVEL:
            return COLOR_BLUE;
        case ULOG_TRACE_LEVEL:
            return COLOR_CYAN;
        default:
            return COLOR_WHITE;
    }
}


// 使用DWT实现时间戳函数
static char* get_dwt_timestamp(void) {
    static char timestamp_str[32];
    uint64_t us = DWT_GetTimeline_us();
    // 格式化为 [秒.微秒] 格式，例如 [123.456789]
    snprintf(timestamp_str, sizeof(timestamp_str), "[%lu.%06lu]", 
             (unsigned long)(us / 1000000),
             (unsigned long)(us % 1000000));
    return timestamp_str;
}

void my_console_logger(ulog_level_t level,char *msg) {
    static char log_buffer[512]; // 静态缓冲区
    int len;
    
    // 获取互斥锁
    tx_mutex_get(&log_mutex, TX_WAIT_FOREVER);
    
#ifdef LOG_COLOR_ENABLE
    // 带颜色的日志输出，添加额外的回车符号
    const char* color = get_color_by_level(level);
    len = snprintf(log_buffer, sizeof(log_buffer), "%s%s [%s]: %s%s\r\n", 
                  color,
                  get_dwt_timestamp(), 
                  ulog_level_name(level), 
                  msg,
                  COLOR_RESET);
#else
    // 不带颜色的日志输出，添加额外的回车符号
    len = snprintf(log_buffer, sizeof(log_buffer), "%s [%s]: %s\r\n", 
                  get_dwt_timestamp(), 
                  ulog_level_name(level), 
                  msg);
#endif

    if (len > 0) {
        #if SHELL_ENABLE
        // 如果Shell启用，使用Shell的发送函数输出日志
        SHELL_UART_SEND((uint8_t*)log_buffer, (uint16_t)len);
        #else
        // 使用UART发送函数输出日志
        if (log_uart != NULL) {
            BSP_UART_Send(log_uart, (uint8_t*)log_buffer, (uint16_t)len);
        } 
        #endif
    }
    // 释放互斥锁
    tx_mutex_put(&log_mutex);
}



void ulog_port_init(void)
{
    // 初始化互斥锁
    tx_mutex_create(&log_mutex, "Log Mutex", TX_NO_INHERIT);

#if SHELL_ENABLE
#else
    // 初始化UART设备
    // UART配置
    UART_Device_init_config log_uart_cfg = {
        .huart = &LOG_SETTING_UART,  
        .expected_len = 0,
        .rx_buf = NULL,
        .rx_buf_size = 0,
        .rx_mode = UART_MODE_IT,
        #if LOG_ASYNC_ENABLE
        .tx_mode = UART_MODE_DMA,
        #else
        .tx_mode = UART_MODE_BLOCKING,
        #endif
        .timeout = 1000,
        .rx_complete_cb = NULL,
        .cb_type = UART_CALLBACK_EVENT,
        .event_flag = UART_RX_DONE_EVENT,
    };

    log_uart = BSP_UART_Device_Init(&log_uart_cfg);
#endif
    ULOG_INIT();
    ULOG_SUBSCRIBE(my_console_logger, LOG_LEVEL_INFO);
}


